package com.ns.scs.task.excutor;

import com.ns.basic.dict.entry.DictItemEntry;
import com.ns.basic.dict.mapper.DictEntryMapper;
import com.ns.basic.dict.mapper.DictItemEntryMapper;
import com.ns.basic.server.mapper.ServerEntryMapper;
import com.ns.core.current.config.SymbolsMark;
import com.ns.core.current.config.SysConst;
import com.ns.core.enums.GeneralEnum;
import com.ns.core.utils.bean.ServiceUtil;
import com.ns.core.utils.cache.RedisUtil;
import com.ns.core.utils.sg.ResultError;
import com.ns.core.vo.bs.BaseVO;
import com.ns.scs.ads.mapper.AdsSpaceEntryMapper;
import com.ns.scs.rsr.mapper.CategoryEntryMapper;
import com.ns.scs.tags.mapper.TagsEntryMapper;
import com.ns.scs.task.excutor.basic.ScheduledBasicActuator;
import com.ns.scs.task.init.TaskValidUtils;
import com.ns.scs.task.mapper.ScheduledActuatorMapper;
import com.ns.scs.task.mapper.ScheduledTaskMapper;
import com.ns.scs.task.service.IScheduledTaskLogsService;
import com.ns.scs.task.vo.ScheduledTaskVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 服务同步执行器执行器
 * <p>
 * 执行定时任务业务类
 *
 * @author liao.wei
 * @since 2024/11/11
 */
@Slf4j
public class ScheduleSyncDictActuator extends ScheduledBasicActuator {
    public ScheduleSyncDictActuator(ScheduledTaskVO scheduledTask) {
        super(scheduledTask);
    }

    @Override
    public void run() {
        ScheduledTaskVO scheduledTask = super.getScheduledTask();
        IScheduledTaskLogsService scheduledTaskLogsService = ServiceUtil.getBean(IScheduledTaskLogsService.class);
        try {
            // 校验任务和执行器状态
            if (!TaskValidUtils.isTaskValid(scheduledTask)) {
                return;
            }
            // 更新任务状态
            ScheduledTaskMapper taskMapper = ServiceUtil.getBean(ScheduledTaskMapper.class);

            taskMapper.updateExecStatus(SymbolsMark.ONE, scheduledTask.getId());
            // 删除字典缓存
            RedisUtil.stringRedisTemplate.delete(SysConst.PROJECT_TAG + SymbolsMark.COLON + SymbolsMark.COLON + SysConst.PROJECT_DICT);
            ServiceUtil.getBean(RedisUtil.class);
            // 同步服务到字典
            syncServerToDict();
            // 同步执行器到字典
            syncActuatorToDict();
            // 同步资源类型到字典
            syncCategoryToDict();
            // 同步标签到字典
            syncTagsToDict();
            // 同步广告位到字典
            syncAdsLocationToDict();
            // 更新任务状态
            taskMapper.updateExecStatus(SymbolsMark.TWO, scheduledTask.getId());
            // 记录日志
            scheduledTaskLogsService.saveLogs(scheduledTask, SymbolsMark.TWO, null);
        } catch (Exception e) {
            throw new ResultError(scheduledTaskLogsService.saveLogs(scheduledTask, SymbolsMark.ONE, e));
        }
    }

    /**
     * 同步标签到字典
     */
    private void syncAdsLocationToDict() {
        // 获取服务
        AdsSpaceEntryMapper mapper = ServiceUtil.getBean(AdsSpaceEntryMapper.class);
        List<BaseVO> svs = mapper.getOptions();
        if (!CollectionUtils.isEmpty(svs)) {
            saveAdsDict(svs);
        }
    }

    /**
     * 保存广告字典
     *
     * @param svs 参数
     */
    private void saveAdsDict(List<BaseVO> svs) {
        // 字典
        DictEntryMapper dictMapper = ServiceUtil.getBean(DictEntryMapper.class);
        BaseVO idName = dictMapper.getByCode(GeneralEnum.DICT.ADS_LOCATION_ID_NAME.getKey());
        BaseVO codeId = dictMapper.getByCode(GeneralEnum.DICT.ADS_LOCATION_CODE_ID.getKey());
        if (Objects.nonNull(svs)) {
            // 字典项
            DictItemEntryMapper dictItemMapper = ServiceUtil.getBean(DictItemEntryMapper.class);
            // 先删除再新增
            dictItemMapper.delByDictId(idName.getId());
            dictItemMapper.delByDictId(codeId.getId());
            List<DictItemEntry> items = getDictItemEntries(svs, idName, codeId);
            if (!CollectionUtils.isEmpty(items)) {
                dictItemMapper.insertOrUpdate(items);
            }
        }

    }

    /**
     * 封装数据
     *
     * @param svs    数据
     * @param idName idName
     * @param codeId codeId
     * @return DictItemEntry
     */
    private static List<DictItemEntry> getDictItemEntries(List<BaseVO> svs, BaseVO idName, BaseVO codeId) {
        List<DictItemEntry> items = new ArrayList<>(svs.size());
        for (BaseVO sv : svs) {
            DictItemEntry dictItemName = new DictItemEntry();
            dictItemName.setDictId(idName.getId());
            dictItemName.setCode(String.valueOf(sv.getId()));
            dictItemName.setName(sv.getName());
            dictItemName.setSort(1L);
            items.add(dictItemName);

            DictItemEntry dictItemCode = new DictItemEntry();
            dictItemCode.setDictId(codeId.getId());
            dictItemCode.setCode(sv.getCode());
            dictItemCode.setName(String.valueOf(sv.getId()));
            dictItemCode.setSort(1L);
            items.add(dictItemCode);
        }
        return items;
    }

    /**
     * 同步标签到字典
     */
    private void syncTagsToDict() {
        // 获取服务
        TagsEntryMapper mapper = ServiceUtil.getBean(TagsEntryMapper.class);
        List<BaseVO> svs = mapper.getOptions();
        if (!CollectionUtils.isEmpty(svs)) {
            // 字典
            DictEntryMapper dictMapper = ServiceUtil.getBean(DictEntryMapper.class);
            BaseVO dict = dictMapper.getByCode(GeneralEnum.DICT.TAGS.getKey());
            saveDict(svs, dict, false);
        }
    }


    /**
     * 同步资源类型到字典
     */
    private void syncCategoryToDict() {
        CategoryEntryMapper mapper = ServiceUtil.getBean(CategoryEntryMapper.class);
        List<BaseVO> svs = mapper.getCategory();
        if (!CollectionUtils.isEmpty(svs)) {
            // 类别
            List<BaseVO> bsc = new ArrayList<>();
            // 类型
            List<BaseVO> bst = new ArrayList<>();
            for (BaseVO sv : svs) {
                if (ObjectUtils.isEmpty(sv.getPid())) {
                    bsc.add(sv);
                } else {
                    bst.add(sv);
                }
            }
            // 字典
            DictEntryMapper dictMapper = ServiceUtil.getBean(DictEntryMapper.class);
            BaseVO dict = dictMapper.getByCode(GeneralEnum.DICT.RESOURCE_CATEGORY.getKey());
            saveDict(bsc, dict, false);
            BaseVO dictType = dictMapper.getByCode(GeneralEnum.DICT.RESOURCE_TYPE.getKey());
            saveDict(bst, dictType, false);
        }
    }

    /**
     * 同步服务到字典
     */
    private static void syncServerToDict() {
        // 获取服务
        ServerEntryMapper serverMapper = ServiceUtil.getBean(ServerEntryMapper.class);
        List<BaseVO> svs = serverMapper.getServer();
        if (!CollectionUtils.isEmpty(svs)) {
            // 字典
            DictEntryMapper dictMapper = ServiceUtil.getBean(DictEntryMapper.class);
            BaseVO dict = dictMapper.getByCode(GeneralEnum.DICT.SD.getKey());
            saveDict(svs, dict, true);
        }
    }


    /**
     * 同步执行器到字典
     */
    private static void syncActuatorToDict() {
        ScheduledActuatorMapper actuatorMapper = ServiceUtil.getBean(ScheduledActuatorMapper.class);
        // 获取执行器
        List<BaseVO> svs = actuatorMapper.getActuator();
        if (!CollectionUtils.isEmpty(svs)) {
            // 字典
            DictEntryMapper dictMapper = ServiceUtil.getBean(DictEntryMapper.class);
            BaseVO dict = dictMapper.getByCode(GeneralEnum.DICT.ACTUATORS.getKey());
            saveDict(svs, dict, false);
        }
    }

    /**
     * 保存字典
     *
     * @param svs  参数
     * @param dict 字典对象
     */
    private static void saveDict(List<BaseVO> svs, BaseVO dict, boolean suffix) {
        if (Objects.nonNull(dict)) {
            // 字典项
            DictItemEntryMapper dictItemMapper = ServiceUtil.getBean(DictItemEntryMapper.class);
            // 先删除再新增
            dictItemMapper.delByDictId(dict.getId());
            List<DictItemEntry> items = new ArrayList<>(svs.size());
            for (int i = 0; i < svs.size(); i++) {
                BaseVO baseVO = svs.get(i);
                DictItemEntry dictItemEntry = new DictItemEntry();
                dictItemEntry.setDictId(dict.getId());
                dictItemEntry.setCode(String.valueOf(baseVO.getId()));
                if (suffix) {
                    dictItemEntry.setName(baseVO.getName() + SymbolsMark.COLON + baseVO.getCode());
                } else {
                    dictItemEntry.setName(baseVO.getName());
                }
                dictItemEntry.setSort((long) i);
                items.add(dictItemEntry);
            }
            dictItemMapper.insertOrUpdate(items);
        }
    }
}